package com.meixun.xuanke.user.service.impl;

import com.meixun.xuanke.user.dao.UserDao;
import com.meixun.xuanke.user.model.User;
import com.meixun.xuanke.user.service.UserService;
import com.meixun.xuanke.user.util.StuUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private RedisTemplate<String, User> redisTemplate;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private UserDao userDao;


    @Override
    public User login(String userName, String pass) {

        User user = null;
        String key ="userInfo:userName_"+userName+"_pass_"+pass+"_*";
        Set<String> keys=scan(key);

        for(String key0 : keys){
            user=redisTemplate.opsForValue().get(key0);
        }
        if(user==null){
            List<User> list=userDao.getUserListByLogin(userName,pass);
            if(list.size()>0){
                user=list.get(0);
                redisTemplate.opsForValue().set("userInfo:userName_"+user.getUserName()+"_pass_"+user.getPass()+"_schoolid_"+user.getSchoolId()+"_userid_"+user.getUserId(), user, 30, TimeUnit.DAYS);
            }
        }
        return user;
    }

    @Override
    public User getUserByUserId(String userId) {
        User user = null;
        String key ="userInfo:*_userid_"+userId;
        Set<String> keys = scan(key);

        for(String key0 : keys){
            user=redisTemplate.opsForValue().get(key0);
        }
        if(user==null){
            List<User> list=userDao.getUserListByUserId(userId);
            if(list.size()>0){
                user=list.get(0);
                redisTemplate.opsForValue().set("userInfo:userName_"+user.getUserName()+"_pass_"+user.getPass()+"_schoolid_"+user.getSchoolId()+"_userid_"+user.getUserId(), user, 30, TimeUnit.DAYS);
            }
        }
        return user;
    }


    @Override
    public Integer getGrade(String stuUserId) {
        HashMap hashMap=userDao.queryGrade(stuUserId);
        return hashMap==null?null: StuUtil.getGrade(Integer.parseInt(hashMap.get("Grade").toString()),Integer.parseInt(hashMap.get("ClassTypeID").toString()));
    }

    @Override
    public void init() {
        long time =System.currentTimeMillis();
        List<User> list=userDao.getUserListAll();
        for (int i = 0; i <list.size(); i++) {
            User user =list.get(i);
            redisTemplate.opsForValue().set("userInfo:userName_"+user.getUserName()+"_pass_"+user.getPass()+"_schoolid_"+user.getSchoolId()+"_userid_"+user.getUserId(), user, 30, TimeUnit.DAYS);
        }

        logger.info("********************缓存用户结束************************** 用时："+(System.currentTimeMillis()-time));
    }

    @Override
    public void initBySchool(String schoolId) {
        List<User> list=userDao.getUserListBySchool(schoolId);
        for (int i = 0; i <list.size(); i++) {
            User user =list.get(i);
            redisTemplate.opsForValue().set("userInfo:userName_"+user.getUserName()+"_pass_"+user.getPass()+"_schoolid_"+user.getSchoolId()+"_userid_"+user.getUserId(), user, 30, TimeUnit.DAYS);
            getGrade(user.getStuUserId());
        }
    }

    @Override
    public void initByUser(String userId) {
        List<User> list=userDao.getUserListByUserId(userId);
        for (int i = 0; i <list.size(); i++) {
            User user =list.get(i);
            redisTemplate.opsForValue().set("userInfo:userName_"+user.getUserName()+"_pass_"+user.getPass()+"_schoolid_"+user.getSchoolId()+"_userid_"+user.getUserId(), user, 30, TimeUnit.DAYS);
        }
    }
    public Set<String> scan(String pattern){
        Set<String> set = redisTemplate.execute(new RedisCallback<Set<String>>() {

            @Override
            public Set<String> doInRedis(RedisConnection connection) throws DataAccessException {

                Set<String> binaryKeys = new HashSet<>();

                Cursor<byte[]> cursor = connection.scan( new ScanOptions.ScanOptionsBuilder().match(pattern).count(Long.MAX_VALUE).build());
                while (cursor.hasNext()) {
                    binaryKeys.add(new String(cursor.next()));
                }
                return binaryKeys;
            }
        });
        return set;
    }

}
